package com.wx.commons.annotation;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.wx.commons.model.SysLog;
import com.wx.commons.utils.IpAddressUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Date;

@Aspect
@Component
public class OperationLogAspect {

    //定义切点 @Pointcut
    //在注解的位置切入代码
    @Pointcut("@annotation(com.wx.commons.annotation.OperationLog)")
    public void logPointCut() {
    }

    //切面 配置通知
    @AfterReturning("logPointCut()")
    public void saveSysLog(JoinPoint joinPoint) {

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作
        OperationLog operation = method.getAnnotation(OperationLog.class);
        if (operation != null) {
            String value = operation.value();
            //获取请求的类名
            String className = joinPoint.getTarget().getClass().getName();
            //获取请求的方法名
            String methodName = method.getName();
            String methodStr = (className + "." + methodName);
            //获取用户ip地址
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String url = request.getRequestURI();
            String ip = IpAddressUtil.getIpAddress(request);
            // 请求参数
            String params = getParams(joinPoint);
            //保存日志
            SysLog sysLog = SysLog.builder()
                    .ip(ip)
                    .url(url)
                    .method(methodStr)
                    .param(params)
                    .desc(value)
                    .date(new Date())
                    .build();
            System.out.println(sysLog);
        }
    }

    private String getParams(JoinPoint joinPoint) {
        // 构造参数组集合
        JSONObject allParams = new JSONObject();
        for (Object arg : joinPoint.getArgs()) {
            allParams.putAll(JSONUtil.parseObj(arg));
        }
        String params = "";
        if (!allParams.isEmpty()) {
            params = allParams.toString();
        }
        if(params.length()> 1000){
            params = params.substring(0,997).concat("...");
        }
        return params;
    }

}

